/**
 * @Author       : Hejh(3010733382@qq.com)
 * @Version      : V1.0
 * @Date         : 2024-01-24 19:27:55
 * @Description  : 存储源管理的控制器
 */
const { default: mongoose } = require('mongoose')
const { Op } = require('sequelize')
const { StorageOrigin } = require('@/framework/mongoose')
const R = require('@/models/Response')
const { File } = require('@/models/model')
const { ERROR_USER_CODE } = require('@/constants/errorCode')
const {
  THIRD_STORAGE_ARR,
  KODO_STORAGE,
  UUS_STORAGE
} = require('@/constants/storage')
const Mysequelize = require('../models')

/**
 * 列表查询存储源接口
 * @param {*} ctx
 * @returns
 */
module.exports.listStorageOrigin = async (ctx) => {
  const { page, pageSize } = ctx.query
  const total = await StorageOrigin.countDocuments() // 获取总记录数
  const pages = Math.ceil(total / pageSize) // 计算总页数
  let storageOrigins = await StorageOrigin.find()
    .skip((page - 1) * pageSize) // 计算偏移量
    .limit(pageSize)
    .lean() // 设置每页数量

  storageOrigins = storageOrigins.map((item) => {
    if (item.accessSecret) {
      item.accessSecret = item.accessSecret.replace(/./g, '*')
    }
    item.id = item._id
    return item
  })

  ctx.body = R.success({
    page,
    pageSize,
    total,
    pages,
    items: storageOrigins
  })
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description:
 * @param {*} isDefault 是否为默认存储源
 * @param {*} session 事务对象
 */
const updateDefault = async (isDefault, session) => {
  if (+isDefault === 1) {
    // 如果是默认字段为1，需要将其他存储源的isDefault字段设置为0
    await StorageOrigin.updateMany(
      {},
      {
        isDefault: 0
      },
      {
        session
      }
    )
  }
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description:
 * @param {*} ctx
 * @param {*} type 存储源类型
 * @param {*} initObj 初始创建或者更新对象
 */
const getAddAndUpdateObj = (ctx, type, initObj) => {
  const { accessKey, accessSecret, endPoint, bucketName } = ctx.request.body

  // 根据type的不同处理
  if (type === KODO_STORAGE) {
    // 七牛云
  } else if (type === UUS_STORAGE) {
    // 又拍云
  } else if (THIRD_STORAGE_ARR.includes(type)) {
    // 其他三方存储
    initObj = {
      ...initObj,
      accessKey,
      accessSecret,
      endPoint,
      bucketName
    }
  } else {
    // 本地存储
  }

  return initObj
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: 创建存储源接口
 * @param {*} ctx
 */
module.exports.createStorageOrigin = async (ctx) => {
  const { type, name, path, sizeMax, isDefault } = ctx.request.body
  const t = await mongoose.startSession()
  let createObj = {
    name,
    type,
    path,
    sizeMax,
    isDefault,
    createUser: ctx.user.id,
    updateUser: ctx.user.id
  }

  // 根据type的不同，处理createObj
  createObj = getAddAndUpdateObj(ctx, type, createObj)

  t.startTransaction()
  try {
    // 如果是默认字段为1，需要将其他存储源的isDefault字段设置为0
    await updateDefault(createObj.isDefault, t)

    // 到这里可以进行存储源的添加了,排序字段默认是最大值
    // const storageOrigin = await StorageOrigin.create([createObj], {
    //   session: t
    // })
    await new StorageOrigin(createObj).save({ session: t })
    await t.commitTransaction()
    // ctx.logs = {
    //   roldId: storageOrigin.id
    // }
    ctx.body = R.success()
  } catch (error) {
    console.log(error)
    await t.abortTransaction()
    ctx.body = R.error(ERROR_USER_CODE.STORAGE_ORIGIN_CREATE_ERROR)
  } finally {
    t.endSession()
  }
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: 更新存储源接口
 * @param {*} ctx
 */
module.exports.updateStorageOrigin = async (ctx) => {
  const { storageOriginId, name, path, sizeMax, isDefault } = ctx.request.body
  const t = await mongoose.startSession()
  let updateObj = {
    name,
    path,
    sizeMax,
    isDefault
  }
  // 根据type的不同处理是否要更新access系列字段
  // 更新的时候根据id查询type，看一些信息是否必须
  const so = await StorageOrigin.findById(storageOriginId).select('type')
  updateObj = getAddAndUpdateObj(ctx, so.type, updateObj)

  t.startTransaction()
  try {
    // 如果是默认存储源，需将其他存储源isDefault设置为0
    await updateDefault(updateObj.isDefault, t)

    // 进行存储源信息的更新
    await StorageOrigin.updateOne(
      {
        _id: storageOriginId
      },
      updateObj,
      {
        session: t
      }
    )
    await t.commitTransaction()
    ctx.body = R.success()
  } catch (e) {
    await t.abortTransaction()
    ctx.body = R.error(ERROR_USER_CODE.STORAGE_ORIGIN_UPDATE_ERROR)
  } finally {
    t.endSession()
  }
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: 批量删除存储源接口
 * @param {*} ctx
 */
module.exports.delStorageOrigins = async (ctx) => {
  const { storageOriginIds } = ctx.request.body
  const t = await mongoose.startSession()
  const mysqlt = await Mysequelize.transaction()
  console.log(storageOriginIds)

  t.startTransaction()
  // 当前默认存储源不能删除，如果删除也需进行数据的迁移到当前默认存储源
  try {
    await StorageOrigin.deleteMany(
      { _id: { $in: storageOriginIds } },
      { session: t }
    )

    const defaultSo = await StorageOrigin.findOne({
      isDefault: 1
    })
      .select('_id')
      .lean()

    console.log(defaultSo)

    // 修改source对于的storageOriginID为默认存储源ID
    File.update(
      {
        storageOriginId: defaultSo._id.toString()
      },
      {
        where: {
          storageOriginId: {
            [Op.in]: storageOriginIds
          }
        },
        transaction: mysqlt
      }
    )

    await t.commitTransaction()
    await mysqlt.commit()
    ctx.body = R.success()
  } catch {
    await t.abortTransaction()
    await mysqlt.rollback()
    ctx.body = R.error(ERROR_USER_CODE.STORAGE_ORIGIN_DEL_ERROR)
  } finally {
    t.endSession()
  }
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: 设置默认存储源接口
 * @param {*} ctx
 */
module.exports.setDefaultStorageOrigin = async (ctx) => {
  const { storageOriginId } = ctx.request.body
  const t = await mongoose.startSession()
  t.startTransaction()
  try {
    // 将其他存储源的default字段设置为0
    await updateDefault(1, t)

    await StorageOrigin.updateOne(
      {
        _id: storageOriginId
      },
      {
        isDefault: 1
      },
      {
        session: t
      }
    )
    await t.commitTransaction()
    ctx.body = R.success()
  } catch {
    await t.abortTransaction()
    ctx.body = R.error(ERROR_USER_CODE.STORAGE_ORIGIN_SET_DEFAULT_ERROR)
  } finally {
    t.endSession()
  }
}
